﻿using STHPMS1.Common.C_Entity;
using STHPMS1.Common.C_Entity.Stmpms1;
using STHPMS1.ICore;
using STHPMS1.ICore.I_Core;
using STHPMS1.ICore.I_UI;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Web.Http;
using STHPMS1.Common.C_Extension;
using STHPMS1.Web.W_Model;
using System.Collections.Generic;
using Newtonsoft.Json;
using STHPMS1.Common.C_Utils;
using System.Data;
using System.Reflection;
using System.Linq.Expressions;
using System.Web.Caching;

namespace STHPMS1.Web.W_Controller.Decision.Needs
{


    [RoutePrefix("api/DiviResultChart")]
    public class DiviResultChartController : STHPMS1.Web.W_Core.MyController
    {
        [Route("search")]
        public IHttpActionResult SearchData(string rdid,int dir)
        {
            try
            {
                //if(!this.Scene.Bll.B_Roadway.CheckRoadDir(rdid,dir))
                //{
                //    throw new Exception("此路线没有该指定方向");
                //}
                //原始路段结束编号集合
                //IEnumerable<B_Invntory> bList = this.Scene.Bll.B_Invntory.GetOrderByList<B_Invntory>(rdid, dir);
                DataTable b_List = this.Scene.Bll.B_Invntory.GetOrderByList(rdid, dir);
                if (b_List.Rows.Count==0)
                {
                    throw new Exception("此路线指定方向上还没有划分原始路段");
                }

                

                List<double> pci = new List<double>();
                List<double> pqi = new List<double>();
                List<double> sri = new List<double>();
                List<double> pssi = new List<double>();
                List<double> rqi = new List<double>();
                List<int> beginmp = new List<int>();
                //查询该路线指定方向的单元评定数据
                DataTable u_e = this.Scene.Bll.B_Unit.GetUnitZBByRdid(rdid, dir);
                //原始路段终点桩号
                string segIdlist = "";
                //foreach (B_Invntory b in bList)
                foreach (DataRow b in b_List.Rows)
                {
                    segIdlist += Convert.ToDouble(b["Endmp"]) + ",";

                }
                segIdlist = segIdlist.Substring(0, segIdlist.Length - 1);
                segIdlist = "[" + segIdlist + "]";

                //PCI 数据
                string pciValue = "";
                //PQI 数据
                string pqiValue = "";
                //SRI 数据
                string sriValue = "";
                //RQI数据
                string rqiValue = "";
                //PSSI数据
                string pssiValue = "";
                foreach (DataRow dr in u_e.Rows)
                {
                    if (dr["pci"] != null && dr["pci"].ToString() != "")
                        pciValue += "[" + Convert.ToDouble(dr["endmp"]) + "," + Math.Round(Convert.ToDouble(dr["pci"]), 2) + "],";
                    if (dr["pqi"] != null && dr["pqi"].ToString() != "")
                        pqiValue += "[" + Convert.ToDouble(dr["endmp"]) + "," + Math.Round(Convert.ToDouble(dr["pqi"]), 2) + "],";
                    if (dr["sri"] != null && dr["sri"].ToString() != "")
                        sriValue += "[" + Convert.ToDouble(dr["endmp"]) + "," + Math.Round(Convert.ToDouble(dr["sri"]), 2) + "],";
                    if (dr["rqi"] != null && dr["rqi"].ToString() != "")
                        rqiValue += "[" + Convert.ToDouble(dr["endmp"]) + "," + Math.Round(Convert.ToDouble(dr["rqi"]), 2) + "],";
                    if (dr["pssi"] != null && dr["pssi"].ToString() != "")
                        rqiValue += "[" + Convert.ToDouble(dr["endmp"]) + "," + Math.Round(Convert.ToDouble(dr["pssi"]), 2) + "],";
                }

                if(pciValue.Length>0)   pciValue = GetNewJson("PCI", pciValue);
                if (pqiValue.Length > 0) pqiValue = GetNewJson("PQI", pqiValue);
                if (sriValue.Length > 0) sriValue = GetNewJson("SRI", sriValue);
                if (rqiValue.Length > 0) rqiValue = GetNewJson("RQI", rqiValue);
                if (pssiValue.Length > 0) pssiValue = GetNewJson("PSSI", pssiValue);

                ////PQI 数据
                //string pqiValue = "";
                //foreach (double mp in pqi)
                //{
                //    pqiValue += mp + ",";
                //}
                //pqiValue = pqiValue.Substring(0, pqiValue.Length - 1);//去掉最后一个逗号
                //pqiValue = "{name: 'PQI',data:[" + pqiValue + "]}";

               

                //series数据
                string returnValue = @"[" ;
                if(pciValue!="")
                {
                    returnValue += pciValue + ",";
                }
                if(pqiValue!="")
                {
                    returnValue += pqiValue + ",";
                }
                if (sriValue != "")
                {
                    returnValue += sriValue + ",";
                }
                if (rqiValue != "")
                {
                    returnValue += rqiValue + ",";
                }
                if (pssiValue != "")
                {
                    returnValue += pssiValue + ",";
                }
                if(returnValue.Length>1)
                {
                    returnValue = returnValue.Substring(0, returnValue.Length - 1);//去掉最后一个逗号
                }  
                else  //没有任何检测数据
                {
                    string temp="";
                    //只保存原始路段终点桩号
                    //foreach (B_Invntory b in bList)
                    foreach (DataRow b in b_List.Rows)
                    {
                        temp += "[" + Convert.ToDouble(b["Endmp"]) + ",0],";
                    }
                    returnValue += GetNewJson("无检测数据", temp);
                    //returnValue += "{name: '无检测数据',data:[[2000,0],[2745.83,0],[4000,0],[5000,0],[6300,0],[6900,0],[8000,0],[9000,0],[10000,0],[11000,0],[12222,0],[13000,0],[14015.36,0],[15000,0],[16300,0],[17000,0],[17500,0],[18000,0],[18888,0],[20000,0],[21000,0],[22000,0],[23000,0],[24000,0],[25000,0],[26000,0],[27000,0],[28000,0],[29000,0],[2000,0],[31045.16,0],[32000,0],[32500,0]]}";
                }
                returnValue += "]";

                //x轴
                string xAxisCategories = "[0]"; //tempCategories;

                //路线总长度
                double lenth = this.Scene.Bll.B_Roadway.GetLength(rdid);
                if (lenth == 0.0)
                {
                    throw new Exception("此路线没有该方向");
                }
               
                //匿名类
                var rel = new
                {
                    categories = xAxisCategories, //x轴
                    series = returnValue, //单元评定值
                    segIds = segIdlist, //原始路段终点桩号
                    tickInterval = Convert.ToInt32( lenth/5) //X轴间距
                };

                //System.Web.HttpContext.Current.Response.Write(JsonConvert.SerializeObject(rel));
                //System.Web.HttpContext.Current.Response.End();
                return Ok(JsonConvert.SerializeObject(rel));
            }
            catch(Exception ex)
            {
                var response = new HttpResponseMessage(HttpStatusCode.InternalServerError)
                {
                    Content = new StringContent(ex.Message),
                    ReasonPhrase = "Server Error"
                };
                throw new HttpResponseException(response);
            }
        }


        /// <summary>
        /// 去掉最后一个逗号,返回新的Json格式字符串
        /// </summary>
        /// <param name="name"></param>
        /// <param name="str"></param>
        /// <returns></returns>
        private string GetNewJson(string name,string str)
        {
            str = str.Substring(0, str.Length - 1);//去掉最后一个逗号
            return "{name: '"+name+"',data:[" + str + "]}";
        }


        [Route("searchRoad")]
        public IHttpActionResult GetRoad()
        {
            var data = this.Scene.Bll.B_Roadway.GetAll<B_Roadway>();
            if (data == null) return NotFound();
            return Ok(data);
        }
        [Route("searchDir")]
        public IHttpActionResult GetDir(string rdid)
        {
            int dirCount = this.Scene.Bll.B_Roadway.GetDir(rdid);
            DataTable dt = new DataTable();
            dt.Columns.Add(new DataColumn("id"));
            dt.Columns.Add(new DataColumn("text"));
            if(dirCount==1)
            {
                DataRow dr = dt.NewRow();
                dr[0] = (int)Common.C_Enum.DirectionEnum.All13;
                dr[1] = Common.C_Enum.DirectionEnum.All13.GetEnumDescription();
                dt.Rows.Add(dr);
            }
            else
            {
                DataRow dr = dt.NewRow();
                dr[0] = (int)Common.C_Enum.DirectionEnum.Up11;
                dr[1] = Common.C_Enum.DirectionEnum.Up11.GetEnumDescription();
                dt.Rows.Add(dr);
                DataRow dr2 = dt.NewRow();
                dr2[0] = (int)Common.C_Enum.DirectionEnum.Down12;
                dr2[1] = Common.C_Enum.DirectionEnum.Down12.GetEnumDescription();
                dt.Rows.Add(dr2);
            }
            return Ok(dt);
        }


        [Route("")]
        [Route("page/{page?}", Name = "GetDiviResultChartByPage")]
        [Route("rows/{rows?}")]
        [Route("page/{page?}/rows/{rows?}")]
        public IHttpActionResult Get(string rdid = null, string dir = null, int page = 1, int rows = 10)
        {
            int p = page;
            int s = rows;

            PagingInfo info = new PagingInfo();
            info.PageIndex = p > 0 ? p - 1 : 0;
            info.PageSize = s;
            info.TotalRecords = 0;
            //条件

            var data = this.Scene.Bll.Dn_Divi_Result.GetNewRoad<Dn_Divi_Result>(rdid, dir, info);
            if (data == null) return NotFound();

            var result = new { rows = data, total = info.TotalRecords };

            return Ok(result);
        }

        [Route("clear")]
        public void Clear(string rdid = null, string dir = null)
        {
            //删除原来的养护路段和单元关联
            this.Scene.Bll.Dn_Divi_Result.ClearOtherChart(rdid, dir);
        }        

        [Route("divide")]
         public void PostDivide(string rdid = null, string dir = null, string endmp=null)
        {
            try
            {
                //获取新的终点桩号
                List<string> newMp = new List<string>();
                if(endmp!= null && endmp!="")
                {
                    string[] temp = endmp.Split(',');
                    newMp.AddRange(temp);
                }
                List<Dn_Divi_Result> newList = new List<Dn_Divi_Result>();//保存养护划分路段
                List<B_Invntory_Unit> b_i_u_List = new List<B_Invntory_Unit>();//养护路段和关联单元
                List<B_Unit> b_units = this.Scene.Bll.B_Unit.GetUnitList<B_Unit>(dir, rdid);//得到此路线指定方向的单元

                //根据路线和方向查询路段
                IEnumerable<B_Invntory> b_Invntorys = this.Scene.Bll.B_Invntory.GetOrderByList<B_Invntory>(rdid, int.Parse(dir));
                //时间戳
                string time = DateTime.Now.ToShortDateString();
                string segIdlist = "";
                foreach(B_Invntory b in b_Invntorys)
                {
                    //构建新的养护路段和关联单元
                    SetResult(b, newMp, b_units, time, newList, b_i_u_List, ref segIdlist);
                }
                //删除原来的养护路段和单元关联(一条路线一个方向只允许有一次决策路段划分)
                this.Scene.Bll.Dn_Divi_Result.ClearOtherChart(rdid, dir);
                //保存养护路段和单元关联
                this.Scene.Bll.Dn_Divi_Result.SaveAll(newList.ToArray(), b_i_u_List.ToArray());

                
                segIdlist = segIdlist.Substring(0, segIdlist.Length - 1);
                segIdlist = "[" + segIdlist + "]";
                //匿名类
                var rel = new
                {
                      segIds = segIdlist
                };
                System.Web.HttpContext.Current.Response.Write(JsonConvert.SerializeObject(rel));
                System.Web.HttpContext.Current.Response.End();
            }
            catch (Exception ex)
            {
                System.Web.HttpContext.Current.Response.Write(ex.Message);
                System.Web.HttpContext.Current.Response.End();
            }
        }

        /// <summary>
        /// 创建一个新的养护路段
        /// </summary>
        /// <param name="b">旧路段</param>
        /// <param name="m">新的桩号</param>
        /// <param name="time">时间戳</param>
        /// <returns></returns>
        private Dn_Divi_Result GetNewDivi(B_Invntory b,string time,double beginMp)
        {
            Dn_Divi_Result divi = new Dn_Divi_Result();

            divi.Mainsegid = "JCLD_" + b.Rdwayid + "_" + beginMp + "_" + (Common.C_Enum.DirectionEnum)b.Direction_Dictid + "_" + time.Replace("-","").Replace(":","");//养护路段编号
            //其他属性-----------------------------------
           
            divi.Segid = b.Segid;//原始路段编号
            divi.Divi_Time = time;//划分时间
            divi.Rdwayid = b.Rdwayid;//路段所属线路编号
            divi.Direction_Dictid = b.Direction_Dictid;//方向
            divi.Mainneed_Way = "";//养护需求分析类型
            divi.Pvmttype_Dictid = b.Pvmttype_Dictid;//面层类型
            divi.Basictype_Dictid = b.Basictype_Dictid;//基层类型
            divi.Segid_Main = -1;//养护类型
            divi.Admdiv = b.Admdiv;//行政区域
            divi.Admgrd = b.Admgrd;//行政等级 
            divi.Rdclass_Dictid = b.Rdclass_Dictid;//技术等级
            divi.Basictype_Dictid = b.Basictype_Dictid;//基层类型
            divi.Pvmttype_Dictid = b.Pvmttype_Dictid;//面层类型
            divi.Manaut = b.Manaut;//管养单位
            divi.BeginDate = b.Begindate;//通车时间
            divi.His_Version = b.His_Version;//版本号
            divi.ModelGroup_PCI = b.Modelgroup_Pci;//pci模型组
            divi.Numlanes = b.Numlanes;//车道数
            return divi;
        }

        /// <summary>
        /// 遍历单元并添加到单元路段集合
        /// </summary>
        /// <param name="b_unit">所有单元</param>
        /// <param name="newDivi">新的养护路段</param>
        /// <param name="b_i_u_List">路段单元集合</param>
        private void AddTo(List<B_Unit> b_unit,Dn_Divi_Result newDivi,List<B_Invntory_Unit> b_i_u_List)
        {
            foreach (B_Unit u in b_unit)//遍历单元
            {
                if (u.Beginmp >= newDivi.Beginmp && u.Endmp <= newDivi.Endmp)
                {
                    B_Invntory_Unit b_i_u = new B_Invntory_Unit()
                    {
                        Relatedid = Guid.NewGuid().ToString(),
                        Segid = newDivi.Mainsegid,
                        Unit = u.Unit,
                        Rdwayid = newDivi.Rdwayid
                    };
                    b_i_u_List.Add(b_i_u);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="b">路段</param>
        /// <param name="endmp">终点装哈</param>
        /// <param name="b_unit">单元集合</param>
        /// <param name="time">时间戳</param>
        /// <param name="newDivi">养护路段集合</param>
        /// <param name="b_i_u_List">路段单元关联集合</param>
        /// <param name="newSegIds">养护路段的终点桩号</param>
        private void SetResult(B_Invntory b,List<string> endmp,List<B_Unit> b_unit,string time, List<Dn_Divi_Result> newDivi, List<B_Invntory_Unit> b_i_u_List,ref string newSegIds)
        {
            string old_m = "";
            List<double> allMp = new List<double>();

            foreach(string m in endmp)
            {
                if(b.Beginmp< double.Parse(m) && b.Endmp>double.Parse(m)) //如果新桩号在此旧路段范围内，则分开多个新路段
                {
                    allMp.Add(double.Parse(m));

                }
            }
            if (allMp.Count > 0)
            {
                allMp.Add(b.Beginmp);
                allMp.Add(b.Endmp);
                allMp.Sort(); //先排序

                for (int i=0;i<allMp.Count-1;i++ )
                {
                    Dn_Divi_Result divi = GetNewDivi(b, time, allMp[i]);
                    divi.Beginmp = allMp[i];//新的起点桩号
                    divi.Endmp = allMp[i+1];//新的结束桩号
                    newDivi.Add(divi);//添加
                    AddTo(b_unit, divi, b_i_u_List);//添加到路段单元集合 
                    newSegIds += allMp[i + 1] + ",";
                }
            }
            else //路段还是采用旧有模式
            {
                Dn_Divi_Result divi = GetNewDivi(b,time,b.Beginmp);
                divi.Beginmp = b.Beginmp;//新的起点桩号
                divi.Endmp = b.Endmp;//新的结束桩号
                newDivi.Add(divi);//添加
                AddTo(b_unit, divi, b_i_u_List);//添加到路段单元集合 
                newSegIds += b.Endmp + ",";
            }
        }


        //路段养护类型---------------------------------------------------------------------------------------------------------------------------------------------------
        [Route("divide_test")]
        public void PostDivideTest(string rdid, string gf, string zb,string dir)
        {
            try
            {  
               
                List<Dn_Divi_Result> tempList = new List<Dn_Divi_Result>();
                //查询决策路段和最新对应的指标评价平均值
                DataTable dt = this.Scene.Bll.Dn_Divi_Result.GetRoadAvgZB(rdid, dir);
                //遍历路段
                foreach (DataRow row in dt.Rows)
                {
                    //技术等级
                    int _RDCLASS_DICTID = Convert.ToInt32(row["RDCLASS_DICTID"]);
                    List<string> gs = GetGS(gf, _RDCLASS_DICTID, Convert.ToInt32(zb));//返回路段的计算公式(多个)
                    //根据公式得到养护类型
                    int yhtemp = GetYH(gs, row);
                    Dn_Divi_Result divi = new Dn_Divi_Result() {
                        //Divi_Time = row["divi_time"].ToString(), //规划年度
                        Segid_Main = yhtemp, //养护类型
                        Mainneed_Way = gf+"_"+zb,//养护需求分析方法
                        Beginmp = Convert.ToDouble(row["BEGINMP"]),//起点桩号
                        Endmp = Convert.ToDouble(row["ENDMP"]),//终点桩号
                        Mainsegid = row["SEGID"].ToString() //决策路段                       
                    };
                    if (row["PCI"] != null && row["PCI"].ToString()!="")//平均PCI
                    {
                        divi.Pci = Convert.ToDouble(row["PCI"]);
                    }
                    if (row["PQI"] != null && row["PQI"].ToString() != "")//平均PQI
                    {
                        divi.Pqi = Convert.ToDouble(row["PQI"]);
                    }
                    if (row["PSSI"] != null && row["PSSI"].ToString() != "")//平均PSSI
                    {
                        divi.Pssi = Convert.ToDouble(row["PSSI"]);
                    }
                    if (row["RQI"] != null && row["RQI"].ToString() != "")//平均RQI
                    {
                        divi.Rqi = Convert.ToDouble(row["RQI"]);
                    }
                    if (row["SRI"] != null && row["SRI"].ToString() != "")//平均RQI
                    {
                        divi.Sri = Convert.ToDouble(row["SRI"]);
                    }
                    tempList.Add(divi);
                }
                System.Web.HttpContext.Current.Response.Write(JsonConvert.SerializeObject(tempList));
                System.Web.HttpContext.Current.Response.End();
            }
            catch(Exception ex)
            {
                System.Web.HttpContext.Current.Response.Write(ex.Message);
                System.Web.HttpContext.Current.Response.End();
            }
        }

        //返回路段的计算公式
        private List<string> GetGS(string gf, int js, int zb)
        {
            if (Common.C_Definition.MyCacheTools.IsCacheExist(gf + "_" + js + "_" + zb))
            {
                return (List<string>)Common.C_Definition.MyCacheTools.GetCache(gf + "_" + js + "_" + zb);
            }
            else
            {
                List<string> gs = new List<string>();
                if (js >= Common.C_Enum.RoadClassEnum.R162.GetEnumValue()) { js = 162; } //二级公路
                else { js = 160; } //一级以上公路

                if (gf == "0") //国家规范
                {
                    List<Dn_Stand_Wan> stand = this.Scene.Bll.Dn_Stand_Wan.GetList<Dn_Stand_Wan>(zb, js);
                    foreach (Dn_Stand_Wan s in stand)
                    {
                        gs.Add(s.Standsql + ":" + s.Main_Type); //公式和养护类型对应
                    }

                }
                else //华美规范
                {
                    List<Dn_Huamei_Way> hm = this.Scene.Bll.Dn_Huamei_Way.GetList<Dn_Huamei_Way>(zb, js);
                    foreach (Dn_Huamei_Way s in hm)
                    {
                        gs.Add(s.Standsql + ":" + s.Main_Type); //公式和养护类型对应
                    }
                }
                //公式放到缓存
                Common.C_Definition.MyCacheTools.SetCache(gf + "_" + js + "_" + zb, gs, 5);
                return gs;
            }
        }

        /// <summary>
        /// 返回养护类型
        /// </summary>
        /// <param name="gs">路段公式</param>
        /// <param name="zb">指标</param>
        /// <param name="row">单元计算数据</param>
        /// <returns></returns>
        private int GetYH(List<string> gs, DataRow row)
        {
            foreach (string temp in gs)
            {
                string[] tempGS = temp.Split(':'); //将公式和养护类型分割
                if (tempGS[0].Contains("PCI"))
                {
                    if (row["PCI"] == null || row["PCI"].ToString() == "") throw new Exception("缺少PCI数据，无法根据此选项划分路段");
                    tempGS[0] = tempGS[0].Replace("PCI", row["PCI"].ToString());
                }
                if (tempGS[0].Contains("PSSI"))
                {
                    if (row["PSSI"] == null || row["PSSI"].ToString() == "") throw new Exception("缺少PSSI数据，无法根据此选项划分路段");
                    tempGS[0] = tempGS[0].Replace("PSSI", row["PSSI"].ToString());
                }
                if (tempGS[0].Contains("RQI"))
                {
                    if (row["RQI"] == null || row["RQI"].ToString() == "") throw new Exception("缺少RQI数据，无法根据此选项划分路段");
                    tempGS[0] = tempGS[0].Replace("RQI", row["RQI"].ToString());
                }
                if (tempGS[0].Contains("PQI"))
                {
                    if (row["PQI"] == null || row["PQI"].ToString() == "") throw new Exception("缺少PQI数据，无法根据此选项划分路段");
                    tempGS[0] = tempGS[0].Replace("PQI", row["PQI"].ToString());
                }
                if (tempGS[0].Contains("SRI"))
                {
                    if (row["SRI"] == null || row["SRI"].ToString() == "") throw new Exception("缺少SRI数据，无法根据此选项划分路段");
                    tempGS[0] = tempGS[0].Replace("SRI", row["SRI"].ToString());
                }
                if (Common.C_Utils.Evaluator.EvaluateToBool(tempGS[0]))//公式执行
                {
                    return Convert.ToInt32(tempGS[1]);
                }
               
            }
            return -1;
        }

        [Route("divi")]
        public void EditRiviYH()
        {
            try
            {
                List<Dn_Divi_Result> newList = JsonConvert.DeserializeObject<List<Dn_Divi_Result>>(System.Web.HttpContext.Current.Request.Params["data"]);
                ICore.I_Entity.Stmpms1.IDn_Divi_Result[] temp = newList.ToArray();
                //将集合更新到数据库
                this.Scene.Bll.Dn_Divi_Result.Update(temp);
            }
            catch(Exception ex)
            {
                throw ex;
            }
        }
       
    }
}